﻿using MessageWorkflow;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using MessageWorkflow.Graph;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace MessageWorkflow.Test.Graph
{

    [TestClass]
    public class GraphExtensionsTest
    {
        private IGraph<string> LoadExampleGraph()
        {
            AdjacencyGraphTest graphTest = new AdjacencyGraphTest();

            var graph = graphTest.CreateEmptyGraph();
            graphTest.LoadTestData(graph);

            return graph;
        }

        [TestMethod]
        public void Successors_Can_Be_Resolved()
        {
            var graph = LoadExampleGraph();

            var successorNodes = graph.GetSuccessors("Paris");

            Assert.IsTrue(successorNodes.Single() == "Rome");
        }

        [TestMethod]
        public void Successors_Can_Be_Resolved_Flattened()
        {
            var graph = LoadExampleGraph();

            var successorNodes = graph.GetSuccessorsFlattened("Paris");
            var expectedNodes = new string[]
            {
                "Rome",
                "HongKong",
                "Shanghai",
                "Tokyo",
                "New York",
                "London",
                "Chicago"
            };

            Assert.IsFalse(successorNodes.Any(x => !expectedNodes.Contains(x)));
            Assert.IsFalse(expectedNodes.Any(x => !successorNodes.Contains(x)));
        }

        [TestMethod]
        public void Predecessors_Can_Be_Resolved_Flattened()
        {
            var graph = LoadExampleGraph();

            var predecessorNodes = graph.GetPredecessorsFlattened("New York");
            var expectedNodes = new string[]
            {
                "Chicago",
                "Shanghai",
                "HongKong",
                "Rome",
                "Paris",
                "Amsterdam",
                "Tokyo"

            };

            Assert.IsFalse(predecessorNodes.Any(x => !expectedNodes.Contains(x)));
            Assert.IsFalse(expectedNodes.Any(x => !predecessorNodes.Contains(x)));
        }

        [TestMethod]
        public void Sub_Graph_Can_Be_Constructed()
        {
            var graph = LoadExampleGraph();
            string[] nodesToSelect = new string[]
            {
                "Paris",
                "Rome",
                "London",
                "HongKong"
            };

            var subGraph = graph.BuildSubGraph(nodesToSelect);

            Assert.IsTrue(subGraph.Nodes.Count() == nodesToSelect.Count());
        }

        [TestMethod]
        public void Action_Can_Be_Executed_Orderly()
        {
            var graph = LoadExampleGraph();

            List<string> transformOutput = new List<string>();

            foreach (var orderedNode in graph.AsOrdered())
            {
                transformOutput.Add(orderedNode);
            }

            for (int index = 0; index < transformOutput.Count; index++)
            {
                Assert.AreEqual(transformOutput[index], graph.Nodes.ElementAt(index));
            }
        }
    }
}
